package com.pioneer.web.book.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pioneer.common.exception.CustomException;
import com.pioneer.common.utils.SecurityUtils;
import com.pioneer.web.book.domain.Book;
import com.pioneer.web.book.domain.BorrowRecord;
import com.pioneer.web.book.mapper.BookMapper;
import com.pioneer.web.book.service.IBookService;
import com.pioneer.web.book.service.IBorrowRecordService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.pioneer.common.constant.BookConstants.BOOK_STATUS_NOT_RETURN;

/**
* @author aom-star@outlook.com
* @description 针对表【book】的数据库操作Service实现
* @createDate 2025-05-18 10:19:53
*/
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book>
    implements IBookService {
    @Resource
    private BookMapper bookMapper;

    @Resource
    private IBorrowRecordService borrowRecordService;

    @Override
    public boolean updateBook(Book book) {
        Book selecteBook = bookMapper.selectById(book.getId());
        if (selecteBook == null) {
            throw new CustomException("图书不存在喵");
        }
        // 防止修改图书数量
        book.setTotal(null);
        book.setStock(null);

        int ret = bookMapper.updateById(book);
        if (ret <= 0) {
            throw new CustomException("更新图书失败喵");
        }
        return true;
    }

    @Override
    public boolean deleteBook(List<Long> bookIds) {
        List<Book> bookList = listByIds(bookIds);
        if (bookList.isEmpty()) {
            throw new CustomException("图书不存在喵");
        }
        for (Book book : bookList) {
            if (!Objects.equals(book.getStock(), book.getTotal())) {
                throw new CustomException("《" + book.getTitle() + "》图书存在借出，不能删除喵");
            }
        }
        boolean result = bookMapper.deleteByBookIds(bookList);
        if (!result) {
            throw new CustomException("删除图书失败喵");
        }
        // 删除相应的借书记录
        LambdaQueryWrapper<BorrowRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(BorrowRecord::getBookId, bookIds);
        borrowRecordService.remove(wrapper);
        return true;
    }

    @Override
    public boolean addBook(Book book) {
        if (bookMapper.uniqueBook(book.getTitle(), book.getAuthor()) != null) {
            throw new CustomException("图书已存在喵");
        }
        book.setStock(book.getTotal());
        return save(book);
    }

    @Override
    public boolean borrowBook(List<Long> bookIds) {
        List<Book> books = listByIds(bookIds);
        if (CollUtil.isEmpty(books)) {
            throw new CustomException("图书不存在喵");
        }

        List<BorrowRecord> records = borrowRecordService.selectRecordByUserID(SecurityUtils.getLoginUser().getUserId(), BOOK_STATUS_NOT_RETURN);
        // 校验用户是否重复借书
        // 提取出用户当前借阅的图书 ID 集合
        Set<Long> currentlyBorrowedBookIds = records.stream()
                .map(BorrowRecord::getBookId)
                .collect(Collectors.toSet());
        // 过滤出重复的图书
        List<Book> duplicatedBooks = books.stream()
                .filter(book -> currentlyBorrowedBookIds.contains(book.getId()))
                .toList();
        if (!duplicatedBooks.isEmpty()) {
            // 有重复借阅
            throw new CustomException("你有部分图书尚未归还，不能重复借阅喵");
        }
        // 同时正在借阅总数不得超过8本
        if (records.size() + books.size() >= 8) {
            throw new CustomException("用户借阅数量不能超过8本，请先归还或减少借阅喵");
        }

        for (Book book : books) {
            // 校验当前库存是否足够
            if (book.getStock().compareTo(BigDecimal.ZERO) == 0) {
                throw new CustomException("《" + book.getTitle() + "》图书库存不足喵");
            }
            BigDecimal newStock = book.getStock().subtract(BigDecimal.ONE);
            // 创建一条借书记录
            borrowRecordService.borrowBook(book.getId());
            // 更新库存
            Book update = new Book();
            update.setId(book.getId());
            update.setStock(newStock);
            boolean ret = updateById(update);
            if (!ret) {
                throw new CustomException("更新库存数量时失败喵");
            }
        }
        return true;
    }

}




